/**
 * 小时定时器, 整点醒来
 * handle必须有一个支持boost::asio::io_service引用的构造, 重载操作符(), 其中有一个time_t参数
 * 
 * 开发者   : Marco
 * 创建时间 : 2016年7月30日, 下午9:29
 */

#ifndef __MARCO_BST_HOUR_TIMER_HPP__
#define __MARCO_BST_HOUR_TIMER_HPP__

#ifdef __cplusplus

#include <boost/asio/deadline_timer.hpp>
#include <boost/asio/placeholders.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/bind.hpp>

#include <marco/time_utility.h>

namespace marco {
namespace bst {
    
template <typename handle> class hour_timer {
public:
    explicit hour_timer(boost::asio::io_service& io_service) : io_service(io_service), timer(io_service)  {
	time_t cur_timesec = time(NULL);
	int sub = get_next_hour_second(cur_timesec);
	timer.expires_from_now(boost::posix_time::seconds(sub));
	timer.async_wait(boost::bind(&hour_timer::timerHandle, this, boost::asio::placeholders::error, cur_timesec+sub));
    }
    
private:
    /**
     * 定时器超时处理函数
     * @param err 错误码
     */
    void timerHandle(const boost::system::error_code& err, time_t timesec) {
	if (err) { // 一般是对象被删除, 才会触发错误
	    return;
	}
	
	boost::shared_ptr<handle> h = boost::make_shared<handle>(io_service);
	(*h)(timesec);
	
	timer.expires_at(timer.expires_at() + boost::posix_time::seconds(3600)); // 下一小时醒
	timer.async_wait(boost::bind(&hour_timer::timerHandle, this, boost::asio::placeholders::error, timesec+3600));  // 异步等待并注册回调函数
    }
    
    boost::asio::deadline_timer timer;
    boost::asio::io_service& io_service;
};

} // namespace bst
} // namespace marco

#endif // __cplusplus
#endif /* __MARCO_BST_HOUR_TIMER_HPP__ */
